home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / kernel / fs / fsPageOps.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-19  |  9.2 KB  |  296 lines

  1. /*
  2.  * fsPageOps.c --
  3.  *
  4.  *    The has the page-in, page-out, and page-copy routines used
  5.  *    by the VM system.
  6.  *
  7.  * Copyright 1987 Regents of the University of California
  8.  * All rights reserved.
  9.  * Permission to use, copy, modify, and distribute this
  10.  * software and its documentation for any purpose and without
  11.  * fee is hereby granted, provided that the above copyright
  12.  * notice appear in all copies.  The University of California
  13.  * makes no representations about the suitability of this
  14.  * software for any purpose.  It is provided "as is" without
  15.  * express or implied warranty.
  16.  */
  17.  
  18. #ifndef lint
  19. static char rcsid[] = "$Header: /cdrom/src/kernel/Cvsroot/kernel/fs/fsPageOps.c,v 1.12 91/11/02 18:08:34 jhh Exp $ SPRITE (Berkeley)";
  20. #endif not lint
  21.  
  22.  
  23. #include <sprite.h>
  24. #include <fs.h>
  25. #include <fsio.h>
  26. #include <fsutil.h>
  27. #include <fsNameOps.h>
  28. #include <fscache.h>
  29. #include <fsStat.h>
  30. #include <fsdm.h>
  31. #include <fsprefix.h>
  32. #include <rpc.h>
  33. #include <vm.h>
  34. #include <fsrmt.h>
  35. #include <fslcl.h>
  36.  
  37. #include <stdio.h>
  38.  
  39.  
  40. /*
  41.  *----------------------------------------------------------------------
  42.  *
  43.  * Fs_PageRead --
  44.  *
  45.  *    Read in a virtual memory page.  This routine bypasses the cache.
  46.  *
  47.  * Results:
  48.  *    A return status, SUCCESS if successful.
  49.  *
  50.  * Side effects:
  51.  *    The page is filled with data read from the indicate offset.
  52.  *
  53.  *----------------------------------------------------------------------
  54.  */
  55. ReturnStatus
  56. Fs_PageRead(streamPtr, pageAddr, offset, numBytes, pageType)
  57.     Fs_Stream    *streamPtr;    /* Swap file stream. */
  58.     Address    pageAddr;    /* Pointer to page. */
  59.     int        offset;        /* Offset in file. */
  60.     int        numBytes;    /* Number of bytes in page. */
  61.     Fs_PageType    pageType;    /* CODE HEAP or SWAP */
  62. {
  63.     ReturnStatus        status = SUCCESS;
  64.     Fs_IOParam            io;    /* Write parameter block */
  65.     register Fs_IOParam        *ioPtr = &io;
  66.     Fs_IOReply            reply;    /* Return length, signal */
  67.     Boolean            retry;    /* Error retry flag */
  68.  
  69.     FsSetIOParam(ioPtr, pageAddr, numBytes, offset, 0);
  70.     reply.length = 0;
  71.     reply.flags = 0;
  72.     reply.signal = 0;
  73.     reply.code = 0;
  74.     /*
  75.      * We currently copy initialized
  76.      * HEAP pages into the cache.  Also, for non-SWAP
  77.      * pages a client should still check its cache to make sure it
  78.      * didn't just generate the data.
  79.      */
  80.     if ((pageType == FS_SWAP_PAGE) || (pageType == FS_SHARED_PAGE)) {
  81.     ioPtr->flags |= FS_SWAP;
  82.     } else if (pageType == FS_HEAP_PAGE) {
  83.     ioPtr->flags |= FS_HEAP;
  84.     } else if (pageType == FS_CODE_PAGE) {
  85.     ioPtr->flags &= ~(FS_SWAP | FS_HEAP);
  86.     }
  87.  
  88.     do {
  89.     retry = FALSE;
  90.     status = (fsio_StreamOpTable[streamPtr->ioHandlePtr->fileID.type].pageRead) (streamPtr, ioPtr, (Sync_RemoteWaiter *)NIL, &reply);
  91. #ifdef lint
  92.     status = Fsio_FileRead(streamPtr, ioPtr, (Sync_RemoteWaiter *)NIL, &reply);
  93.     status = FsrmtFilePageRead(streamPtr, ioPtr, (Sync_RemoteWaiter *)NIL, &reply);
  94.     status = FspdevPseudoStreamRead(streamPtr, ioPtr, (Sync_RemoteWaiter *)NIL, &reply);
  95.     status = Fsrmt_Read(streamPtr, ioPtr, (Sync_RemoteWaiter *)NIL, &reply);
  96. #endif /* lint */
  97.  
  98.     if (status == RPC_TIMEOUT || status == FS_STALE_HANDLE ||
  99.         status == RPC_SERVICE_DISABLED) {
  100.         /*
  101.          * The server is down so we wait for it.  This blocks
  102.          * the user process doing the page fault.
  103.          */
  104.         Net_HostPrint(streamPtr->ioHandlePtr->fileID.serverID,
  105.             "Fs_PageRead waiting\n");
  106.         status = Fsutil_WaitForRecovery(streamPtr->ioHandlePtr, status);
  107.         if (status == SUCCESS) {
  108.         retry = TRUE;
  109.         } else {
  110.         printf("Fs_PageRead recovery failed <%x>\n", status);
  111.         }
  112.     } else if (status == FS_WOULD_BLOCK) {
  113.         /*
  114.          * The remote server is so hosed that it can't
  115.          * deliver us a block.  There is no good way
  116.          * to wait.  Retry immediately?  Pound pound pound?
  117.          */
  118.         retry = TRUE;
  119.         printf("Fs_PageRead: blocked, waiting 1 min\n");
  120.         (void)Sync_WaitTime(time_OneMinute);
  121.     } else if (status != SUCCESS) {
  122.         printf("Fs_PageRead: Read failed <%x>\n", status);
  123.     }
  124.     } while (retry);
  125.  
  126.     return(status);
  127. }
  128.  
  129. /*
  130.  *----------------------------------------------------------------------
  131.  *
  132.  * Fs_PageWrite --
  133.  *
  134.  *    Write out a virtual memory page.  This is a simplified form of
  135.  *    Fs_Write that invokes the stream's pageWrite operation.  The
  136.  *    stream-specific procedure that is invoked can be the regular
  137.  *    write routine (as it is for local files)  or something more fancy
  138.  *    (as is true for remote files).  This passes the FS_SWAP flag down
  139.  *    to the pageWrite routine so a regular write routine can detect
  140.  *    the difference.
  141.  *
  142.  * Results:
  143.  *    A return status, SUCCESS if successful.
  144.  *
  145.  * Side effects:
  146.  *    The data in the buffer is written to the file at the indicated offset.
  147.  *
  148.  *----------------------------------------------------------------------
  149.  */
  150. ReturnStatus
  151. Fs_PageWrite(streamPtr, pageAddr, offset, numBytes, toDisk)
  152.     Fs_Stream    *streamPtr;    /* Swap file stream. */
  153.     Address    pageAddr;    /* Pointer to page. */
  154.     int        offset;        /* Offset in file. */
  155.     int        numBytes;    /* Number of bytes in page. */
  156.     Boolean    toDisk;        /* TRUE to write through to disk. */
  157. {
  158.     ReturnStatus        status = SUCCESS;
  159.     Fs_IOParam            io;    /* Write parameter block */
  160.     register Fs_IOParam        *ioPtr = &io;
  161.     Fs_IOReply            reply;    /* Return length, signal */
  162.  
  163.     FsSetIOParam(ioPtr, pageAddr, numBytes, offset, FS_SWAP |
  164.         (toDisk? FS_WRITE_TO_DISK : 0));
  165.     reply.length = 0;
  166.     reply.flags = 0;
  167.     reply.signal = 0;
  168.     reply.code = 0;
  169.  
  170.     status = (fsio_StreamOpTable[streamPtr->ioHandlePtr->fileID.type].pageWrite) (streamPtr, ioPtr, (Sync_RemoteWaiter *)NIL, &reply);
  171. #ifdef lint
  172.     status = Fsio_FileWrite(streamPtr, ioPtr, (Sync_RemoteWaiter *)NIL, &reply);
  173.     status = FsrmtFilePageWrite(streamPtr, ioPtr, (Sync_RemoteWaiter *)NIL, &reply);
  174.     status = FspdevPseudoStreamWrite(streamPtr, ioPtr, (Sync_RemoteWaiter *)NIL, &reply);
  175.     status = Fsrmt_Write(streamPtr, ioPtr, (Sync_RemoteWaiter *)NIL, &reply);
  176. #endif /* lint */
  177.  
  178.     return(status);
  179. }
  180.  
  181.  
  182. /*
  183.  *----------------------------------------------------------------------
  184.  *
  185.  * Fs_PageCopy --
  186.  *
  187.  *    Copy the file system blocks in the source swap file to the destination
  188.  *    swap file.  NOTE:  This is still specific to local and remote files.
  189.  *    This means that only Sprite files can be used for swap space.
  190.  *
  191.  * Results:
  192.  *    A return status, SUCCESS if successful.
  193.  *
  194.  * Side effects:
  195.  *    Appropriate blocks in the source file are copied to the dest file.
  196.  *
  197.  *----------------------------------------------------------------------
  198.  */
  199. ReturnStatus
  200. Fs_PageCopy(srcStreamPtr, destStreamPtr, offset, numBytes)
  201.     Fs_Stream    *srcStreamPtr;    /* File to copy blocks from. */
  202.     Fs_Stream    *destStreamPtr;    /* File to copy blocks to. */
  203.     int        offset;        /* Offset in file. */
  204.     int        numBytes;    /* Number of bytes in page. */
  205. {
  206.     int                lastBlock;
  207.     register    Fs_HandleHeader    *srcHdrPtr;
  208.     register    Fs_HandleHeader    *destHdrPtr;
  209.     ReturnStatus        status = SUCCESS;
  210.     int                i;
  211.     Boolean            retry;
  212.     Address            swapPageCopy = (Address) NIL;
  213.     Boolean            swapPageAllocated = FALSE;
  214.  
  215.     if (srcStreamPtr == (Fs_Stream *) NIL) {
  216.     printf("Fs_PageCopy: srcStreamPtr is NIL (failed recovery?)\n");
  217.     return FAILURE;
  218.     }
  219.     if (destStreamPtr == (Fs_Stream *) NIL) {
  220.     printf("Fs_PageCopy: destStreamPtr is NIL (failed recovery?)\n");
  221.     return FAILURE;
  222.     }
  223.     srcHdrPtr = srcStreamPtr->ioHandlePtr;
  224.     destHdrPtr = destStreamPtr->ioHandlePtr;
  225.     lastBlock = (unsigned int) (offset + numBytes - 1) / FS_BLOCK_SIZE;
  226.  
  227.     /*
  228.      * Copy all blocks in the page.
  229.      */
  230.     for (i = (unsigned int) offset / FS_BLOCK_SIZE; i <= lastBlock; i++) {
  231.     do {
  232.         retry = FALSE;
  233.         if (srcHdrPtr->fileID.serverID != destHdrPtr->fileID.serverID) {
  234.         /*
  235.          * The swap files are on different machines, so we need to read
  236.          * from one and write to the other.
  237.          */
  238.         if (!swapPageAllocated) {
  239.             swapPageCopy = (Address) malloc(Vm_GetPageSize());
  240.         }
  241.         swapPageAllocated = TRUE;
  242.         status =
  243.             Fs_PageRead(srcStreamPtr, swapPageCopy, offset,
  244.             numBytes, FS_SWAP_PAGE);
  245.         if (status != SUCCESS) {
  246.             /* Fs_PageRead handles recovery itself, so we don't here. */
  247.             break;
  248.         }
  249.         status =
  250.             Fs_PageWrite(destStreamPtr, swapPageCopy, offset,
  251.             numBytes, TRUE);
  252.         } else {
  253.         status = (fsio_StreamOpTable[srcHdrPtr->fileID.type].blockCopy)
  254.             (srcHdrPtr, destHdrPtr, i);
  255. #ifdef lint
  256.         status = Fsio_FileBlockCopy(srcHdrPtr, destHdrPtr, i);
  257.         status = Fsrmt_BlockCopy(srcHdrPtr, destHdrPtr, i);
  258. #endif /* lint */
  259.         }
  260.         if (status != SUCCESS) {
  261.         if (status == RPC_TIMEOUT || status == RPC_SERVICE_DISABLED ||
  262.             status == FS_STALE_HANDLE) {
  263.             /*
  264.              * The server is down so we wait for it.  This just blocks
  265.              * the user process doing the page fault.
  266.              */
  267.             Net_HostPrint(srcHdrPtr->fileID.serverID,
  268.                 "Fs_PageCopy waiting for recovery\n");
  269.             status = Fsutil_WaitForRecovery(srcStreamPtr->ioHandlePtr,
  270.                 status);
  271.             if (status == SUCCESS) {
  272.             retry = TRUE;
  273.             } else {
  274.             printf("Fs_PageCopy, recovery failed <%x>\n", status);
  275.             if (swapPageAllocated) {
  276.                 free(swapPageCopy);
  277.             }
  278.             return(status);
  279.             }
  280.         } else {
  281.             printf("Fs_PageCopy: Copy failed <%x>\n", status);
  282.             if (swapPageAllocated) {
  283.             free(swapPageCopy);
  284.             }
  285.             return(status);
  286.         }
  287.         }
  288.     } while (retry);
  289.  
  290.     }
  291.     if (swapPageAllocated) {
  292.     free(swapPageCopy);
  293.     }
  294.     return(status);
  295. }
  296.